package com.bailian.web.controller.system;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.bailian.common.annotation.Log;
import com.bailian.common.core.controller.BaseController;
import com.bailian.common.core.domain.AjaxResult;
import com.bailian.common.enums.BusinessType;
import com.bailian.system.domain.BlPark;
import com.bailian.system.domain.vo.BlParkVo;
import com.bailian.system.service.IBlParkService;
import com.bailian.common.utils.poi.ExcelUtil;
import com.bailian.common.core.page.TableDataInfo;
import com.bailian.system.domain.BlParkConfig;
import com.bailian.system.domain.BlParkTags;
import com.bailian.system.domain.BlParkService;
import com.bailian.system.domain.BlWarehouseType;
import javax.validation.constraints.NotNull;
import com.bailian.common.core.domain.BaseEntity;

/**
 * 园区列表Controller
 * 
 * @author bailian
 * @date 2025-08-04
 */
@RestController
@RequestMapping("/system/park")
public class BlParkController extends BaseController
{
    @Autowired
    private IBlParkService blParkService;

    /**
     * 处理园区推荐状态逻辑
     * 确保区域下只有一个推荐园区
     * 
     * @param blPark 园区信息
     */
    private void handleRecommendStatus(BlPark blPark) {
        if (blPark.getIsRecommend() != null && blPark.getIsRecommend() == 1) {
            blParkService.smartUpdateRecommendStatus(blPark.getParkId(), "1");
        }
    }

    /**
     * 查询园区列表列表
     */
    @PreAuthorize("@ss.hasPermi('system:park:list')")
    @GetMapping("/list")
    public TableDataInfo list(BlPark blPark, @RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "10") int pageSize)
    {
        // 原始分页实现：先查询所有数据，然后手动分页
        List<BlParkVo> allList = blParkService.selectListLightweight(blPark);
        
        // 计算分页参数
        int total = allList.size();
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, total);
        
        // 手动分页
        List<BlParkVo> pageList = allList.subList(startIndex, endIndex);
        
        // 构建分页结果
        TableDataInfo dataTable = new TableDataInfo();
        dataTable.setCode(200);
        dataTable.setMsg("查询成功");
        dataTable.setTotal((long) total);
        dataTable.setRows(pageList);
        
        return dataTable;
    }

    /**
     * 导出园区列表列表
     */
    @PreAuthorize("@ss.hasPermi('system:park:export')")
    @Log(title = "园区列表", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, BlPark blPark)
    {
        List<BlParkVo> list = blParkService.selectListLightweight(blPark);
        ExcelUtil<BlParkVo> util = new ExcelUtil<BlParkVo>(BlParkVo.class);
        util.exportExcel(response, list, "园区列表数据");
    }

    /**
     * 获取园区列表详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:park:query')")
    @GetMapping(value = "/{parkId}")
    public AjaxResult getInfo(@PathVariable("parkId") Long parkId)
    {
        BlParkVo vo = blParkService.selectById(parkId);
        return success(vo);
    }

    /**
     * 新增园区列表
     */
    @PreAuthorize("@ss.hasPermi('system:park:add')")
    @Log(title = "园区列表", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody BlPark blPark,
                          @RequestParam(value = "parkConfigIds", required = false) List<Long> parkConfigIds,
                          @RequestParam(value = "serviceIds", required = false) List<Long> serviceIds,
                          @RequestParam(value = "tagIds", required = false) List<Long> tagIds)
    {
        int rows = blParkService.insert(blPark);
        if (rows > 0 && blPark.getParkId() != null)
        {
            // 如果设置为推荐状态，确保区域下只有一个推荐园区
            handleRecommendStatus(blPark);
            
            if (blPark.getHardwareConfig() != null) {
                parkConfigIds = blPark.getHardwareConfig().stream()
                    .map(BlParkConfig::getConfigId)
                    .collect(Collectors.toList());
            }
            if (blPark.getParkTags() != null) {
                tagIds = blPark.getParkTags().stream()
                    .map(BlParkTags::getTagId)
                    .collect(Collectors.toList());
            }
            if (blPark.getParkServices() != null) {
                serviceIds = blPark.getParkServices().stream()
                    .map(BlParkService::getServiceId)
                    .collect(Collectors.toList());
            }
            blParkService.replaceParkConfigs(blPark.getParkId(), parkConfigIds);
            blParkService.replaceParkServices(blPark.getParkId(), serviceIds);
            blParkService.replaceParkTags(blPark.getParkId(), tagIds);
        }
        return toAjax(rows);
    }

    /**
     * 修改园区列表
     */
    @PreAuthorize("@ss.hasPermi('system:park:edit')")
    @Log(title = "园区列表", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody BlPark blPark,
                           @RequestParam(value = "parkConfigIds", required = false) List<Long> parkConfigIds,
                           @RequestParam(value = "serviceIds", required = false) List<Long> serviceIds,
                           @RequestParam(value = "tagIds", required = false) List<Long> tagIds)
    {
        int rows = blParkService.update(blPark);
        if (rows > 0)
        {
            // 如果设置为推荐状态，确保区域下只有一个推荐园区
            handleRecommendStatus(blPark);
            
            if (blPark.getHardwareConfig() != null) {
                parkConfigIds = blPark.getHardwareConfig().stream()
                    .map(BlParkConfig::getConfigId)
                    .collect(Collectors.toList());
            }
            if (blPark.getParkTags() != null) {
                tagIds = blPark.getParkTags().stream()
                    .map(BlParkTags::getTagId)
                    .collect(Collectors.toList());
            }
            if (blPark.getParkServices() != null) {
                serviceIds = blPark.getParkServices().stream()
                    .map(BlParkService::getServiceId)
                    .collect(Collectors.toList());
            }

            blParkService.replaceParkConfigs(blPark.getParkId(), parkConfigIds);
            blParkService.replaceParkServices(blPark.getParkId(), serviceIds);
            blParkService.replaceParkTags(blPark.getParkId(), tagIds);
        }
        return toAjax(rows);
    }

    /**
     * 删除园区列表
     */
    @PreAuthorize("@ss.hasPermi('system:park:remove')")
    @Log(title = "园区列表", businessType = BusinessType.DELETE)
	@DeleteMapping("/{parkIds}")
    public AjaxResult remove(@PathVariable Long[] parkIds)
    {
        return toAjax(blParkService.deleteByIds(parkIds));
    }

    /**
     * 查询推荐园区列表
     */
    @GetMapping("/recommend")
    public AjaxResult getRecommendList(@RequestParam(defaultValue = "10") int limit)
    {
        List<BlParkVo> list = blParkService.selectRecommendList(limit);
        return success(list);
    }

    /**
     * 查询热门园区列表
     */
    @GetMapping("/hot")
    public AjaxResult getHotList(@RequestParam(defaultValue = "10") int limit)
    {
        List<BlParkVo> list = blParkService.selectHotList(limit);
        return success(list);
    }

    /**
     * 根据标签查询园区列表
     */
    @GetMapping("/tag/{tagName}")
    public AjaxResult getByTag(@PathVariable String tagName)
    {
        List<BlParkVo> list = blParkService.selectByTag(tagName);
        return success(list);
    }

    /**
     * 根据仓库类型查询园区列表
     */
    @GetMapping("/warehouse/{warehouseType}")
    public AjaxResult getByWarehouseType(@PathVariable String warehouseType)
    {
        List<BlParkVo> list = blParkService.selectByWarehouseType(warehouseType);
        return success(list);
    }

    /**
     * 根据硬件配置查询园区列表
     */
    @GetMapping("/hardware/{hardwareConfig}")
    public AjaxResult getByHardwareConfig(@PathVariable String hardwareConfig)
    {
        List<BlParkVo> list = blParkService.selectByHardwareConfig(hardwareConfig);
        return success(list);
    }

    /**
     * 根据服务类型查询园区列表
     */
    @GetMapping("/service/{serviceType}")
    public AjaxResult getByServiceType(@PathVariable String serviceType)
    {
        List<BlParkVo> list = blParkService.selectByServiceType(serviceType);
        return success(list);
    }

    /**
     * 根据地理位置查询园区列表
     */
    @GetMapping("/location/{location}")
    public AjaxResult getByLocation(@PathVariable String location)
    {
        List<BlParkVo> list = blParkService.selectByLocation(location);
        return success(list);
    }

    /**
     * 根据推荐状态查询园区列表
     */
    @GetMapping("/recommend-status/{isRecommend}")
    public AjaxResult getByRecommendStatus(@PathVariable String isRecommend)
    {
        List<BlParkVo> list = blParkService.selectByRecommend(isRecommend);
        return success(list);
    }

    /**
     * 查询指定区域下的推荐园区
     */
    @GetMapping("/area/{areaId}/recommend")
    public AjaxResult getRecommendParkByArea(@PathVariable Long areaId)
    {
        List<BlParkVo> list = blParkService.selectByAreaId(areaId);
        // 过滤出推荐园区
        BlParkVo recommendPark = list.stream()
            .filter(park -> park.getIsRecommend() != null && park.getIsRecommend() == 1)
            .findFirst()
            .orElse(null);
        return success(recommendPark);
    }

    /**
     * 根据价格范围查询园区列表
     */
    @GetMapping("/price-range")
    public AjaxResult getByPriceRange(@RequestParam BigDecimal minPrice, @RequestParam BigDecimal maxPrice)
    {
        List<BlParkVo> list = blParkService.selectByPriceRange(minPrice, maxPrice);
        return success(list);
    }

    /**
     * 根据面积范围查询园区列表
     */
    @GetMapping("/area-range")
    public AjaxResult getByAreaRange(@RequestParam BigDecimal minArea, @RequestParam BigDecimal maxArea)
    {
        List<BlParkVo> list = blParkService.selectByAreaRange(minArea, maxArea);
        return success(list);
    }

    /**
     * 根据多个标签查询园区列表
     */
    @PostMapping("/tags")
    public AjaxResult getByTags(@RequestBody String[] tags)
    {
        List<BlParkVo> list = blParkService.selectByTags(tags);
        return success(list);
    }

    /**
     * 根据多个仓库类型查询园区列表
     */
    @PostMapping("/warehouse-types")
    public AjaxResult getByWarehouseTypes(@RequestBody String[] warehouseTypes)
    {
        List<BlParkVo> list = blParkService.selectByWarehouseTypes(warehouseTypes);
        return success(list);
    }

    /**
     * 根据多个硬件配置查询园区列表
     */
    @PostMapping("/hardware-configs")
    public AjaxResult getByHardwareConfigs(@RequestBody String[] hardwareConfigs)
    {
        List<BlParkVo> list = blParkService.selectByHardwareConfigs(hardwareConfigs);
        return success(list);
    }

    /**
     * 根据多个服务类型查询园区列表
     */
    @PostMapping("/service-types")
    public AjaxResult getByServiceTypes(@RequestBody String[] serviceTypes)
    {
        List<BlParkVo> list = blParkService.selectByServiceTypes(serviceTypes);
        return success(list);
    }

    /**
     * 根据可用面积查询园区列表
     */
    @GetMapping("/available-area/{availableArea}")
    public AjaxResult getByAvailableArea(@PathVariable BigDecimal availableArea)
    {
        List<BlParkVo> list = blParkService.selectByAvailableArea(availableArea);
        return success(list);
    }

    /**
     * 根据出租率查询园区列表
     */
    @GetMapping("/rental-rate/{rentalRate}")
    public AjaxResult getByRentalRate(@PathVariable BigDecimal rentalRate)
    {
        List<BlParkVo> list = blParkService.selectByRentalRate(rentalRate);
        return success(list);
    }

    /**
     * 查询最近更新的园区
     */
    @GetMapping("/recently-updated")
    public AjaxResult getRecentlyUpdated(@RequestParam(defaultValue = "10") int limit)
    {
        List<BlParkVo> list = blParkService.selectRecentlyUpdated(limit);
        return success(list);
    }

    /**
     * 查询最新创建的园区
     */
    @GetMapping("/recently-created")
    public AjaxResult getRecentlyCreated(@RequestParam(defaultValue = "10") int limit)
    {
        List<BlParkVo> list = blParkService.selectRecentlyCreated(limit);
        return success(list);
    }

    /**
     * 批量根据ID查询园区信息
     */
    @PostMapping("/batch")
    public AjaxResult getByIds(@RequestBody Long[] parkIds)
    {
        List<BlParkVo> list = blParkService.selectByIds(parkIds);
        return success(list);
    }

    /**
     * 根据综合条件查询园区
     */
    @PostMapping("/complex")
    public AjaxResult getByComplexConditions(@RequestBody Map<String, Object> conditions)
    {
        List<BlParkVo> list = blParkService.selectByComplexConditionsFromMap(conditions);
        return success(list);
    }

    /**
     * 更新园区推荐状态
     */
    @PreAuthorize("@ss.hasPermi('system:park:edit')")
    @Log(title = "更新园区推荐状态", businessType = BusinessType.UPDATE)
    @PutMapping("/{parkId}/recommend/{isRecommend}")
    public AjaxResult updateRecommendStatus(@PathVariable Long parkId, @PathVariable String isRecommend)
    {
        return toAjax(blParkService.smartUpdateRecommendStatus(parkId, isRecommend));
    }

    /**
     * 批量更新园区推荐状态
     */
    @PreAuthorize("@ss.hasPermi('system:park:edit')")
    @Log(title = "批量更新园区推荐状态", businessType = BusinessType.UPDATE)
    @PutMapping("/batch/recommend")
    public AjaxResult batchUpdateRecommendStatus(@RequestBody Map<String, Object> params)
    {
        Long parkId = Long.valueOf(params.get("parkId").toString());
        String isRecommend = params.get("isRecommend").toString();
        return toAjax(blParkService.smartUpdateRecommendStatus(parkId, isRecommend));
    }

    /**
     * 更新园区出租面积
     */
    @PreAuthorize("@ss.hasPermi('system:park:edit')")
    @Log(title = "更新园区出租面积", businessType = BusinessType.UPDATE)
    @PutMapping("/{parkId}/rented-area/{rentedArea}")
    public AjaxResult updateRentedArea(@PathVariable Long parkId, @PathVariable BigDecimal rentedArea)
    {
        return toAjax(blParkService.updateRentedArea(parkId, rentedArea));
    }

    /**
     * 检查园区名称是否存在
     */
    @GetMapping("/check-name")
    public AjaxResult checkNameExists(@RequestParam String parkName, @RequestParam(required = false) Long excludeId)
    {
        int count = blParkService.checkNameExists(parkName, excludeId);
        return success(count > 0);
    }

    /**
     * 获取园区统计信息
     */
    @GetMapping("/statistics")
    public AjaxResult getStatistics()
    {
        int totalCount = blParkService.count(new BlPark());
        int recommendCount = blParkService.countRecommend();
        List<Map<String, Object>> typeStats = blParkService.countByType();
        List<Map<String, Object>> locationStats = blParkService.countByLocation();
        Map<String, Object> priceStats = blParkService.getPriceStatistics();
        Map<String, Object> areaStats = blParkService.getAreaStatistics();
        List<Map<String, Object>> priceRangeStats = blParkService.countByPriceRange();
        List<Map<String, Object>> areaRangeStats = blParkService.countByAreaRange();
        
        return success()
            .put("totalCount", totalCount)
            .put("recommendCount", recommendCount)
            .put("typeStats", typeStats)
            .put("locationStats", locationStats)
            .put("priceStats", priceStats)
            .put("areaStats", areaStats)
            .put("priceRangeStats", priceRangeStats)
            .put("areaRangeStats", areaRangeStats);
    }
}
